////////////////////////////////////////////////////////////////////////////////

#ifndef _SERVERNETWORK_H_
#define _SERVERNETWORK_H_

////////////////////////////////////////////////////////////////////////////////

#ifndef _OBSERVER_H_
#include "observer.h"
#endif

#ifndef _CONNECTION_H_
#include "connection.h"
#endif

#ifndef _COMMONTYPES_H_
#include "commontypes.h"
#endif

#ifndef _ASYNCCALLER_H_
#include "asynccaller.h"
#endif

#include <map>

////////////////////////////////////////////////////////////////////////////////

class Server;
class Packet;
class ServerStatePacket;
class ServerInfoPacket;
class Buffer;

////////////////////////////////////////////////////////////////////////////////


/** Game server network manager
*
*  @author   Roman Pasechnik
*  @since    Jun 11th, 2009
*  @updated  Nov 10th, 2009
*/
class ServerNetwork : public Observer
{
////////////////////////////////////////////////////////////////////////////////

public:

////////////////////////////////////////////////////////////////////////////////


    /** Constructor */
    ServerNetwork();


    /** Destructor */
    virtual ~ServerNetwork();


    /* Start server network */
    void Start( Server* _server );


    /** Does server have disconnected clients? */
    bool HasDisconnectedClients() const;


    /** Delete connections with disconnected clients */
    void DeleteDisconnected();


////////////////////////////////////////////////////////////////////////////////


    /** Send server state to client */
    void SendServerState( int _clientID, const ServerStatePacket& _serverStatePacket );


    /** Send server info to client */
    void SendServerInfo( int _clientID, const ServerInfoPacket& _serverInfoPacket );


////////////////////////////////////////////////////////////////////////////////

private:

////////////////////////////////////////////////////////////////////////////////
//// Observer interface implementation
////////////////////////////////////////////////////////////////////////////////


    /** Notify observer about event */
    virtual void OnEvent( Event _event, Observable* _observable );


////////////////////////////////////////////////////////////////////////////////


    /** Add empty connection and call Accept() on it */
    void AcceptNewConnection();


    /** Handle receive TCP from specific client */
    void HandleReceiveTCP( const Connection& _client );


    /** Handle receive TCP from specific client */
    void HandleReceiveUDP( const Connection& _client );


    /** Disconnect handler */
    void HandleDisconnect( Connection& _client );


    /** Send packet to client */
    void SendTCP( int _clientID, const Buffer& _packet );
    void SendUDP( int _clientID, const Buffer& _packet );


////////////////////////////////////////////////////////////////////////////////


    /** Find connection by ID */
    Connection& FindConnectionByID( int _ID );


////////////////////////////////////////////////////////////////////////////////


    /** Delete connection with specified client */
    void DeleteConnection( int _clientID );


    /** Async connection deleter */
    AsyncCaller m_Deleter;


    /** Server interface */
    Server* m_Server;


    /** [Utility type]: client connections by IDs */
    typedef std::map<int, ConnectionPtr> ConnectionsByIDs;


    /** Connections with clients */
    ConnectionsByIDs m_ConnectionsByIDs;


////////////////////////////////////////////////////////////////////////////////
};


////////////////////////////////////////////////////////////////////////////////

#endif

////////////////////////////////////////////////////////////////////////////////

